using System;
using System.Collections.Generic;
using System.Text;
using System.Xml;
using System.IO;
using Rest;

namespace Rest.Http
{
    /// <summary>
    /// AtomXML encoding
    /// </summary> 
    /// <remarks>
    /// TODO: Can this be implemented as MultipartFormData?
    /// 
    /// Note: I have not yet got node with namespaces to work.
    /// See the example here: http://code.google.com/apis/gdata/calendar.html#add_event. 
    /// This one does not work because of the "gd" namespace nodes.
    /// </remarks> 
    /// <example>
    /// <entry xmlns="http://www.w3.org/2005/Atom">  
    ///   <title type="text">Sample with dates</title>
    ///   <content type='text'></content>
    ///   <author>
    ///     <name>ben.biddington</name>
    ///     <email>ben.biddington@gmail.com</email>
    ///   </author>  
    ///   <where valueString='' />
    ///   <when startTime='2006-12-18T17:57:19.425Z' 
    ///       endTime='2006-12-18T17:57:19.425Z '>
    ///   </when>  
    ///   <updated>2006-12-18T17:57:19.425Z</updated>
    /// </entry>
    /// </example> 
    public class Atom : HttpContentType  
    {
        private String contentType = "application/atom+xml";

        /// <summary>
        /// 
        /// </summary>
        public override string ContentType
        {
            get
            {
                return contentType;
            }
            set
            {
                contentType = value;
            }
        }

        /// <summary>
        /// Write request body to the supplied stream
        /// </summary>
        /// <remarks>
        /// Forced to write to temp MemoryStream here because the XmlTextWriter
        /// closes the stream it operates on. At least we know the capacity to
        /// set it to.
        /// TODO: Even though we are setting the initial capacity, memoryStream
        /// is still resizing itself because of writer.WriteStartDocument().
        /// Can we estimate this so memoryStream does not ever have to resize its
        /// internal array?
        /// </remarks>
        /// <param name="stream"></param>
        /// <param name="parameters"></param>
        /// <param name="dataItems"></param>
        /// <param name="characterEncoding"></param>
        public sealed override void WriteRequestBody(
            Stream stream, 
            RestParameterCollection parameters, 
            RestDataItemCollection dataItems, 
            Encoding characterEncoding)
        {
            if (dataItems != null && dataItems.Count > 0)
            {
                Int32 dataItemLength = dataItems[0].Length;

                if (dataItemLength > 0)
                {
                    using (MemoryStream memoryStream = new MemoryStream(dataItemLength))
                    {
                        using (XmlTextWriter writer = new XmlTextWriter(
                            memoryStream, characterEncoding))
                        {
                            writer.Formatting = Formatting.Indented;
                            writer.WriteStartDocument();

                            String text = characterEncoding.GetString(
                                dataItems[0].GetBytes(), 0, dataItems[0].Length);

                            writer.WriteRaw(text);

                            writer.Flush();
                            memoryStream.WriteTo(stream);
                        }
                    }
                }
            }
        }
    }
}
